package com.roast.util;

import java.util.ArrayList;
import com.roast.domain.*;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class DBBroker {

    Session session;
    Transaction transaction;
    SessionFactory sf;

    public DBBroker() {
    }

    public int openDataBase() {
        try {
            sf = new Configuration().configure().buildSessionFactory();
        } catch (HibernateException ex) {
            System.out.println("DBBroker:openDataBase:[" + ex + "]]");
            return 10001;
        }
        return 10002;
    }

    public int closeDataBase() {
        try {
            sf.close();
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:closeDataBase:[" + ex + "]]");
            return 10003;
        }
        return 10004;
    }

    public int openSession() {
        try {
            session = sf.openSession();
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:openSession:[" + ex + "]]");
            return 10005;
        }
        return 10006;
    }

    public int closeSession() {
        try {
            session.close();
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:closeSession:[" + ex + "]]");
            return 10007;
        }
        return 10008;
    }

    public int beginTransaction() {
        try {
            transaction = session.beginTransaction();
            transaction.begin();
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:beginTransaction:[" + ex + "]]");
            return 10009;
        }
        return 10010;
    }

    public int commit() {
        try {
            transaction.commit();
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:commit:[" + ex + "]]");
            return 10011;
        }
        return 10012;
    }

    public int rollback() {
        try {
            transaction.rollback();
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:rollback:[" + ex + "]]");
            return 10013;
        }
        return 10014;
    }

    public boolean save(DomainObject obj) {
        try {
            session.save(obj);
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:save:[" + ex + "]]");
            return false;
        }
        return true;
    }

    public boolean update(DomainObject obj) {
        try {
            session.update(obj);
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:update:[" + ex + "]]");
            return false;
        }
        return true;
    }

    //READ FROM DATABASE
    public DomainObject readOneByID(QueryObject queryObject) {
        try {
            DomainObject fromDB = (DomainObject) session.get(queryObject.objectClass(), queryObject.getID());
            if (fromDB == null) {
                System.out.println("[DBBroker:readOneByID:FAIL!]");
                queryObject.setSignal(10021);
            } else {
                queryObject.setSignal(10020);
                return fromDB;
            }
        } catch (HibernateException ex) {
            System.out.println("[DBBroker:readOneByID:[" + ex + "]]");
            queryObject.setSignal(10022);
        } catch (ClassCastException ex) {
            System.out.println("[DBBroker:readOneByID:[" + ex + "]]");
            queryObject.setSignal(10023);
        }
        return null;
    }

    public DomainObject readOneByParametar(QueryObject queryObject) {
        ArrayList<Parametar> parametarList = queryObject.getParametarList();
        if (parametarList.isEmpty()) {
            System.out.println("[DBBroker:readOneByParametar:parametarList size=0;!]");
            queryObject.setSignal(10031);
        } else {
            try {
                Query q = session.createQuery(queryObject.getQuery());
                for (int i = 0; i < parametarList.size(); i++) {
                    Parametar parametar = parametarList.get(i);
                    q.setParameter(parametar.getName(), parametar.getValue());
                }
                DomainObject fromDB = (DomainObject) q.uniqueResult();
                if (fromDB == null) {
                    System.out.println("[DBBroker:readOneByParametar:Not found!]");
                    queryObject.setSignal(10032);
                } else {
                    queryObject.setSignal(10030);
                    return fromDB;
                }
            } catch (HibernateException ex) {
                System.out.println("[DBBroker:readOneByParametar:[" + ex + "]]");
                queryObject.setSignal(10033);

            } catch (ClassCastException ex) {
                System.out.println("[DBBroker:readOneByParametar:[" + ex + "]]");
                queryObject.setSignal(10034);
            }
        }
        return null;
    }

    public ArrayList<DomainObject> readMany(QueryObject queryObject) {
        ArrayList<Parametar> parametarList = queryObject.getParametarList();
        if (parametarList.isEmpty()) {
            System.out.println("[DBBroker:readMany:parametarList size=0!]");
            queryObject.setSignal(10041);
        } else {
            try {
                Query q = session.createQuery(queryObject.getQuery());
                for (int i = 0; i < parametarList.size(); i++) {
                    Parametar parametar = parametarList.get(i);
                    q.setParameter(parametar.getName(), parametar.getValue());
                }
                @SuppressWarnings("unchecked")
                ArrayList<DomainObject> result = (ArrayList<DomainObject>) q.list();
                if (result.isEmpty()) {
                    System.out.println("[DBBroker:readMany:[Result list is size 0.]]");
                    queryObject.setSignal(10042);
                } else {
                    queryObject.setSignal(10040);
                    return result;
                }
            } catch (HibernateException ex) {
                System.out.println("[DBBroker:readMany:[" + ex + "]]");
                queryObject.setSignal(10043);
            } catch (ClassCastException ex) {
                System.out.println("[DBBroker:readMany:[" + ex + "]]");
                queryObject.setSignal(10044);
            }
            return null;
        }
        return null;
    }
}
